package controllers

import (
	"context"
	"errors"
	"github.com/gin-gonic/gin"
	"go.didapinche.com/foundation/plat-echo/app/ops/models/request"
	"go.didapinche.com/foundation/plat-echo/app/ops/services"
	"go.didapinche.com/foundation/plat-echo/pkg/constants"
	"go.uber.org/zap"
	"net/http"
	"strconv"
)

type AppController struct {
	service services.AppService
	logger  *zap.Logger
}

func NewAppController(service services.AppService, logger *zap.Logger) *AppController {
	return &AppController{
		service: service,
		logger:  logger.With(zap.String("type", "controller.app")),
	}
}

func (ctl *AppController) Find(c *gin.Context) {
	info := new(request.SlaQuery)

	if err := c.Bind(info); err != nil {
		ctl.logger.Error("bind params error", zap.Error(err))
		c.String(http.StatusBadRequest, "bind params error:%v", err)
		return
	}

	infos, totalCount, err := ctl.service.Find(c.Request.Context(), info)
	if err != nil {
		if errors.Is(err, context.Canceled) {
			ctl.logger.Error("context canceled", zap.Error(err))
			c.Status(constants.StatusRequestCanceled)
			return
		}
		ctl.logger.Error("call server Find  error", zap.Error(err))
		c.String(http.StatusInternalServerError, "call server Find  error:%v", err)
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"data":        infos,
		"total_count": totalCount,
	})
}

func (ctl *AppController) StatByGroup(c *gin.Context) {
	param := new(request.SlaQuery)
	if err := c.BindQuery(param); err != nil {
		ctl.logger.Error("bind param error", zap.Error(err))
		c.String(http.StatusBadRequest, "bind param error:%v", err)
		return
	}

	sla, err := ctl.service.StatByGroup(c.Request.Context(), param)
	if err != nil {
		if errors.Is(err, context.Canceled) {
			ctl.logger.Error("context canceled", zap.Error(err))
			c.Status(constants.StatusRequestCanceled)
			return
		}
		ctl.logger.Error("call SlaService.StatByGroup() error", zap.Error(err))
		c.String(http.StatusInternalServerError, "call SlaService.StatByGroup() error:%v", err)
		return
	}

	c.JSON(http.StatusOK, sla)
}
func (ctl *AppController) StatByAppIDS(c *gin.Context) {
	param := new(request.AppSlaReq)

	if err := c.BindQuery(param); err != nil {
		ctl.logger.Error("bind param error", zap.Error(err))
		c.String(http.StatusBadRequest, "bind param error:%v", err)
		return
	}
	appSlas, err := ctl.service.StatByAppIDS(c.Request.Context(), param)
	if err != nil {
		if errors.Is(err, context.Canceled) {
			ctl.logger.Error("context canceled", zap.Error(err))
			c.Status(constants.StatusRequestCanceled)
			return
		}
		ctl.logger.Error("call SlaService.StatByApp() error", zap.Error(err))
		c.String(http.StatusInternalServerError, "call SlaService.StatByApp() error:%v", err)
		return
	}
	c.JSON(http.StatusOK, appSlas)
}

func (ctl *AppController) ReloadApp(c *gin.Context) {
	id := c.Query("id")
	appID, err := strconv.ParseUint(id, 10, 64)
	if err != nil {
		ctl.logger.Error("call appID parse error", zap.Error(err))
		c.String(http.StatusBadRequest, "bind param error:%v", err)
	}

	go ctl.service.ReloadApp(context.Background(), appID)
	c.JSON(http.StatusOK, "ok")
}
